﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using CardClass;
using System.Windows.Browser;
using System.Collections.Generic;
using System.Threading;
using System.Xml;

namespace SangoClient
{
    [Scriptable]
    public partial class Page : Canvas
    {
        bool HasStarted = false;
        bool HasChar = false;
        bool HasRole = false;
        string isHost;
        
        const int InitialCardsNumber = 4;
        int PlayerNum = 0;
        string myID;

        private int Activity = -1;
        // 0 - kill
        // 1 - cure

        private Downloader downloader;
        List<string> ListPlayer = new List<string>();

        Random random = new Random();

        public Page()
        {
            WebApplication.Current.RegisterScriptableObject("SendMessage", this);
        }

        public void Page_Loaded(object o, EventArgs e)
        {
            // Required to initialize variables
            InitializeComponent();
            this.Visibility = Visibility.Collapsed;
        }

        [Scriptable]
        public event EventHandler<MyEventArgs> CallScriptSendMessage;

        [Scriptable]
        public void GetMessageFromServer(string message)
        {
            if (message == null)
                return;

            string[] MessageString = message.Split(':');
            switch (MessageString[0])  // MessageString[0] : message code, MessageString[1] : message content
            {
                case "Join":
                    this.Visibility = Visibility.Visible;
                    myID = MessageString[1];
                    isHost = MessageString[2];
                    if (isHost == "true")
                        Btn_Start.Visibility = Visibility.Visible;
                    Text_Status.Visibility = Visibility.Visible;
                    ProgressIn.Begin();
                    break;
                case "ClearPlayer":
                    ListPlayer.Clear();
                    PlayersPanel.Children.Clear();
                    PlayerNum = 0;
                    break;
                case "AddPlayer":
                    if (!ListPlayer.Contains(MessageString[1]))
                    {
                        GetPlayer(MessageString[1], "HP:", "Cards:");
                        ListPlayer.Add(MessageString[1]);
                        PlayerNum++;

                        TextBlock tb = new TextBlock();
                        tb.TextDecorations = TextDecorations.Underline;
                        tb.Text = MessageString[1];
                        tb.Cursor = Cursors.Hand;
                        tb.MouseLeftButtonUp += new MouseEventHandler(ActPerson_MouseLeftButtonUp);
                        tb.Foreground = new SolidColorBrush(Colors.Green);
                        tb.SetValue(LeftProperty, 5);
                        tb.SetValue(TopProperty, (PlayerNum - 1) * 20);
                        UserLayer.Children.Add(tb);
                    }
                    break;

                case "roleCard":
                    GetRole(MessageString[1], "longda.png");
                    break;

                case "characterCard":
                    // Update player list
                    foreach (PlayerPanel pp in PlayersPanel.Children)
                    {
                        if (pp.PlayerIDText == MessageString[1])
                        {
                            pp.PlayerIDText = MessageString[1] + "   C:" + MessageString[4];
                            pp.HPText = "HP: " + MessageString[2];
                            pp.CardsText = "Cards: 4";
                        }
                    }

                    if (MessageString[1] == myID)
                    {
                        GetChar(MessageString[4], "S:" + MessageString[3], "HP:" + MessageString[2] + " / " + MessageString[2], "yangweili.png");
                    }
                    break;
                    
                case "gameCard":
                    GetCards(MessageString[1], MessageString[1] + ".png");
                    break;

                case "InitFinished":
                    HasStarted = true;
                    TextBlock t = new TextBlock();
                    t.TextDecorations = TextDecorations.Underline;
                    t.Foreground = new SolidColorBrush(Colors.Purple);
                    t.Text = "cancel";
                    t.MouseLeftButtonUp += new MouseEventHandler(ActPerson_MouseLeftButtonUp);
                    t.Cursor = Cursors.Hand;
                    t.SetValue(LeftProperty, 5);
                    t.SetValue(TopProperty, PlayerNum * 20);
                    UserLayer.Children.Add(t);

                    UserLayerBackground.Fill = new SolidColorBrush(Colors.LightGray);
                    UserLayerBackground.Height = (PlayerNum + 1) * 20 + 10;
                    break;

                case "dispatchCardFinish":
                    TextPanel.Text = "Ready to start";
                    Action.Visibility = Visibility.Visible;

                    // functions for user activity
                    ActKill.MouseLeftButtonUp += new MouseEventHandler(ActKill_MouseLeftButtonUp);
                    ActCure.MouseLeftButtonUp += new MouseEventHandler(ActCure_MouseLeftButtonUp);
                    Text_Status.Text = "Game Starts";
                    break;

                case "Leave":
                    this.Visibility = Visibility.Collapsed;
                    break;
            }
        }

        void ActPerson_MouseLeftButtonUp(object sender, MouseEventArgs e)
        {
            TextBlock tb = sender as TextBlock;
            if (tb.Text == "cancel")
            {
                Activity = -1;
                TextPanel.Text = "Cancel";
                UserLayer.Visibility = Visibility.Collapsed;
                return;
            }

            String messageStr;
            switch (Activity)
            {
                case 0:
                    if (tb.Text == myID)
                    {
                        TextPanel.Text = "Cannot kill yourself";
                        UserLayer.Visibility = Visibility.Collapsed;
                        return;
                    }
                    TextPanel.Text = "Kill " + tb.Text;
                    messageStr = "<message type=\"playerAction\"><action type=\"kill\" target=\"" + tb.Text + "\"></action></message>";
                    CallScriptSendMessage(this, new MyEventArgs(messageStr));
                    break;

                case 1:
                    TextPanel.Text = "Cure " + tb.Text;
                    messageStr = "<message type=\"playerAction\"><action type=\"kill\" target=\"" + tb.Text + "\"></action></message>";
                    CallScriptSendMessage(this, new MyEventArgs(messageStr));
                    break;
            }
            UserLayer.Visibility = Visibility.Collapsed;
            return;
            
        }

        void ActCure_MouseLeftButtonUp(object sender, MouseEventArgs e)
        {
            bool flag = false;
            foreach (var card in CardsPanel.Children)
            {
                CardControlAction actioncard = card as CardControlAction;
                if (actioncard == null)
                    continue;
                if (actioncard.funcText == "Cure")
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                TextPanel.Text = "No Cure in your cards";
                return;
            }

            ClearActs();
            Activity = 1;
            ActCure.Foreground = new SolidColorBrush(Colors.Green);
            UserLayer.SetValue(LeftProperty, e.GetPosition(null).X + 30);
            UserLayer.SetValue(TopProperty, e.GetPosition(null).Y);
            UserLayer.Visibility = Visibility.Visible;

            foreach (var findMe in UserLayer.Children)
            {
                TextBlock tb = findMe as TextBlock;
                if (tb == null)
                    continue;
                if (tb.Text == "cancel")
                    tb.Foreground = new SolidColorBrush(Colors.Purple);
                else
                    tb.Foreground = new SolidColorBrush(Colors.Green);
            }
        }

        void ActKill_MouseLeftButtonUp(object sender, MouseEventArgs e)
        {
            bool flag = false;
            foreach (var card in CardsPanel.Children)
            {
                CardControlAction actioncard = card as CardControlAction;
                if (actioncard == null)
                    continue;
                if (actioncard.funcText == "Kill")
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                TextPanel.Text = "No Kill in your cards";
                return;
            }

            ClearActs();
            Activity = 0;
            ActKill.Foreground = new SolidColorBrush(Colors.Red);
            UserLayer.SetValue(LeftProperty, e.GetPosition(null).X + 30);
            UserLayer.SetValue(TopProperty, e.GetPosition(null).Y);
            UserLayer.Visibility = Visibility.Visible;

            foreach (var findMe in UserLayer.Children)
            {
                TextBlock tb = findMe as TextBlock;
                if (tb == null)
                    continue;
                if (tb.Text == myID)
                    tb.Foreground = new SolidColorBrush(Colors.Gray);
                else if (tb.Text == "cancel")
                    tb.Foreground = new SolidColorBrush(Colors.Purple);
                else
                    tb.Foreground = new SolidColorBrush(Colors.Green);
            }
        }
        
        void ClearActs()
        {
            ActKill.Foreground = null;
            ActCure.Foreground = null;
        }

        void ProgressIn_Completed(object sender, EventArgs e)
        {
            HtmlElement he = HtmlPage.Document.GetElementByID("URLString");
            string str = he.GetAttribute("alt");
            int pos = str.LastIndexOf('/');
            str = str.Substring(0, pos + 1) + "Images/Archive.zip";

            downloader = new Downloader();
            downloader.Completed += new EventHandler(downloader_Completed);
            downloader.DownloadProgressChanged += new EventHandler(downloader_DownloadProgressChanged);

            downloader.Open("get", new Uri(str));
            downloader.Send();
        }

        void downloader_DownloadProgressChanged(object sender, EventArgs e)
        {
            progress.Width = downloader.DownloadProgress * 200;
        }

        void downloader_Completed(object sender, EventArgs e)
        {
            ProgressOut.Begin();
        }

        private void StartGame(object o, EventArgs e)
        {
            if (HasStarted)
                return;

            Btn_Start.Visibility = Visibility.Collapsed;
            CallScriptSendMessage(this, new MyEventArgs(QueryString("startGame")));
        }

        private void GetRole(string role, string image)
        {
            if (HasRole)
                return;
            // Role Card Distribution
            CardControlRole cr = new CardControlRole();
            cr.RoleText = role; //
            cr.SetURI(downloader, image); // 

            cr.Left = 510;
            cr.Top = 90;
            CardsPanel.Children.Add(cr);
            HasRole = true;
        }

        private void GetChar(string charactor, string skill, string hp, string image)
        {
            if (HasChar)
                return;
            // Character Card Distribution
            CardControlChar cc = new CardControlChar();
            cc.CharText = charactor; // 
            cc.SkillText = skill; // 
            cc.HPText = hp; // 
            cc.SetURI(downloader, image); //

            cc.Left = 410;
            cc.Top = 70;
            //cc.Angle = (r.NextDouble() - 0.5) * 60;

            CardsPanel.Children.Add(cc);
            HasChar = true;
        }

        private void GetCards(string func, string image/*, int index*/)
        {
            // Character Card Distribution
            

            CardControlAction cc = new CardControlAction();
            cc.funcText = func;
            cc.SetURI(downloader, image);

            cc.Left = random.NextDouble() * 350;
            cc.Top = random.NextDouble() * 80;
            cc.Angle = (random.NextDouble() - 0.5) * 60;

            CardsPanel.Children.Add(cc);
        }

        private void GetPlayer(string playerid, string hp, string cards)
        {
            PlayerPanel pr = new PlayerPanel();
            pr.PlayerIDText = playerid;
            pr.HPText = hp;
            pr.CardsText = cards;

            pr.Left = 0;
            pr.Top = PlayerNum * pr.Height;

            PlayersPanel.Children.Add(pr);
        }

        private string QueryString(string type)
        {
            return "<message type=\"" + type + "\"></message>";
            
        }

    }

    [Scriptable]
    public class MyEventArgs : EventArgs
    {
        private string msg;

        public MyEventArgs(string messageData)
        {
            msg = messageData;
        }

        [Scriptable]
        public string Message
        {
            get { return msg; }
            set { msg = value; }
        }
    }

}
